/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hyperbeam.Estructuras;

/**
 *
 * @author alberto
 */
public class Vector {
    private double X;
    private double Y;
    private double Z;
    private double Norma;

    // <editor-fold defaultstate="collapsed" desc="Properties">
    /**
     * Obtiene la normal del vector
     * @return
     */
    public double getNorma() {
        return Norma;
    }

    /**
     * Obtiene el componente X
     * @return
     */
    public double getX() {
        return X;
    }

    /**
     * Obtiene el componente Y
     * @return
     */
    public double getY() {
        return Y;
    }

    /**
     * Obtiene el componente Z
     * @return
     */
    public double getZ() {
        return Z;
    }

    public void setNorma(double Norma) {
        this.Norma = Norma;
    }

    public void setX(double X) {
        this.X = X;
    }

    public void setY(double Y) {
        this.Y = Y;
    }

    public void setZ(double Z) {
        this.Z = Z;
    }

    public void setXYZ(double X, double Y, double Z) {
        this.X = X;
        this.Y = Y;
        this.Z = Z;
        this.Normalizar();
    }



    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Métodos Que alteran el vector">
    /**
     * Normaliza un Vector
     */
    public void Normalizar(){
        this.Norma = Math.sqrt(Math.pow(X, 2) + Math.pow(Y, 2) + Math.pow(Z, 2));
        if (Norma != 0){
            this.X /= Norma;
            this.Y /= Norma;
            this.Z /= Norma;
        }     
    }

    /**
     * Escala un vector, altera el original
     * @param factor
     */
    public void Escalar(double factor){
        this.X *= factor;
        this.Y *= factor;
        this.Z *= factor;
    }
    
    /**
     * Suma a un vector otro vector, altera el original
     * @param factor
     */
    public void SumarVector(Vector vec){
        this.X += vec.getX();
        this.Y += vec.getY();
        this.Z += vec.getZ();
    }


    /**
     * Resta a un vector otro vector, altera el original
     * @param factor
     */
    public void RestarVector(Vector vec){
        this.X -= vec.getX();
        this.Y -= vec.getY();
        this.Z -= vec.getZ();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Métodos estaticos">
    /**
     * Escala un vector y devuelve una nueva estructura vector
     * @param factor
     */
    public static Vector VectorEscalado(Vector vec, double factor){
        return new Vector(vec.getX() * factor, vec.getY() * factor, vec.getZ() * factor );
    }

    /**
     * Suma dos vectores y devuelve su suma representado como un nuevo vector
     * @param vec1
     * @param vec2
     * @return
     */
    public static Vector SumarVectores(Vector vec1 , Vector vec2){
        return new Vector(vec1.getX() + vec2.getX(), vec1.getY() + vec2.getY(), vec1.getZ() + vec2.getZ());
    }

    /**
     * Resta dos vectores y devuelve su suma representado como un nuevo vector
     * @param vec1
     * @param vec2
     * @return
     */
    public static Vector RestarVectores(Vector vec1 , Vector vec2){
        return new Vector(vec1.getX() - vec2.getX(), vec1.getY() - vec2.getY(), vec1.getZ() - vec2.getZ());
    }

    /**
     * Retorna el producto punto de dos vectores
     * @param vec1
     * @param vec2
     * @return
     */
    public static double ProductoPunto(Vector vec1 , Vector vec2){
        return (vec1.getX() * vec2.getX() + vec1.getY() * vec2.getY() + vec1.getZ() * vec2.getZ());
    }

    /**
     * Retorna el producto punto de dos vectores
     * @param vec1
     * @param vec2
     * @return
     */
    public static Vector ProductoCruz(Vector vec1 , Vector vec2){
        double newX =   vec1.getY()*vec2.getZ() - vec1.getZ()*vec2.getY();
        double newY = -(vec1.getX()*vec2.getZ() - vec1.getZ()*vec2.getX());
        double newZ =   vec1.getX()*vec2.getY() - vec1.getY()*vec2.getX();
        return new Vector(newX, newY, newZ);
    }
    // </editor-fold>


    /**
     * Representación en forma de string del vector para propositos de verificación
     * @return
     */
    public String ToString(){
        java.lang.StringBuilder builder = new java.lang.StringBuilder("El vector posee los componentes X= ");
        builder.append(Double.toString(X));
        builder.append(" , Y= ");
        builder.append(Double.toString(Y));
        builder.append(" , Z= ");
        builder.append(Double.toString(Z));
        builder.append(" , Norma= ");
        builder.append(Double.toString(Norma));
        return builder.toString();
    }


    /***
     * Constructor
     * @param X
     * @param Y
     * @param Z
     */
    public Vector(double X, double Y, double Z) {
        this.X = X;
        this.Y = Y;
        this.Z = Z;
        this.Normalizar();
    }

    public Vector() {
    }
}
